package com.sixks.app.mvc;

import com.alibaba.fastjson.JSON;
import com.sixks.app.AliExpressConstant;
import com.sixks.app.api.ApiCallService;
import com.sixks.app.api.auth.AuthService;
import com.sixks.app.api.utils.CommonUtil;
import com.sixks.app.api.utils.SecurityUtil;
import com.sixks.app.api.utils.StringUtil;
import com.sixks.app.dao.CategoryDao;
import com.sixks.app.domain.Category;
import com.sixks.app.domain.ExpressUser;
import com.sixks.app.domain.MemoryStore;
import com.sixks.app.mvc.cmd.*;
import com.sixks.app.mvc.cmd.exception.ExpressAPIException;
import com.sixks.app.mvc.cmd.exception.UploadPicResponse;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Controller;
import org.springframework.ui.ModelMap;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestMethod;
import org.springframework.web.bind.annotation.RequestParam;
import org.springframework.web.bind.annotation.ResponseBody;
import org.springframework.web.multipart.MultipartFile;

import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.io.IOException;
import java.io.InputStream;
import java.io.PrintWriter;
import java.util.*;

/**
 * 运费模板
 * 服务模板
 * 类目
 * 属性
 * 上传图片
 * [
 * {
 * "attrNameId": "326",
 * "attrName": "999",
 * "attrValueId": "200001275",
 * "attrValue": "2 - 5 kg"
 * },
 * {
 * "attrNameId": "327",
 * "attrName": "199",
 * "attrValueId": "200001276",
 * "attrValue": "3 - 8 kg"
 * }
 * ]
 */
@Controller
@RequestMapping("/")
public class HomeController {

    public static final String CUR_USER = "cur_user";

    private static final Logger logger = LoggerFactory.getLogger(HomeController.class);

    @Autowired
    private MemoryStore memoryStore;

    @Autowired
    private CategoryDao categoryDao;

    @RequestMapping(method = RequestMethod.GET)
    public String printWelcome(HttpServletRequest request, ModelMap model) {
        logger.info("test.....");
//        ExpressUser user = (ExpressUser) request.getSession().getAttribute(CUR_USER);
//        if (user == null) {
//            return "login";
//        }
        //

//        List<Order> os = this.orderDao.loadOrderByDate(DateUtil.parseStr2Date("2014-02-13", DateUtil.DATE_FORMAT_DEFAULT),DateUtil.parseStr2Date("2014-02-14", DateUtil.DATE_FORMAT_DEFAULT));
        model.addAttribute("message", "Hello world!");
        Map<String, String> ps = new TreeMap<String, String>(new MapKeyComparator());
        ps.put("client_id", AliExpressConstant.APP_KEY);
        ps.put("redirect_uri", AliExpressConstant.REDIRECT_URL);
        ps.put("site", AliExpressConstant.SITE);

        String sign = CommonUtil.signatureWithParamsOnly(ps, AliExpressConstant.SIGN);
        StringBuilder sb = new StringBuilder();
        sb.append("client_id").append("=").append(ps.get("client_id")).append("&");
        sb.append("site").append("=").append(ps.get("site")).append("&");
        sb.append("redirect_uri").append("=").append(ps.get("redirect_uri")).append("&");
        sb.append("_aop_signature=").append(sign);
        model.put("url", AliExpressConstant.SERVER + sb.toString());


        return "login";
    }

    @RequestMapping(value = "logout", method = RequestMethod.GET)
    public String logout(HttpServletRequest request) {
        request.getSession().setAttribute(CUR_USER, null);
        request.getSession().invalidate();
        return "login";
    }

    @RequestMapping(value = "test", method = RequestMethod.GET)
    public String test(HttpServletRequest request) {
        return "test";
    }

    @RequestMapping(value = "home", method = RequestMethod.GET)
    public String home(HttpServletRequest request, ModelMap model) {
        ExpressUser user = (ExpressUser) request.getSession().getAttribute(CUR_USER);
        if (user == null) {
            return "redirect:/";
        }

        List<Category> categories = this.categoryDao.loadAll();
        model.put("categories", categories);
        model.put("id", user.getUserName());
        return "home";
    }

    @RequestMapping("/alibabacallback")
    public String printJson(HttpServletRequest request, ModelMap model) {
        JSONResponse json = new JSONResponse();
        json.setMessage(request.getParameter("code"));
        json.setState("ok");
        //
        String code = request.getParameter("code");

        Map<String, String> params = new HashMap<String, String>();
        params.put("grant_type", "authorization_code");
        params.put("need_refresh_token", "true");
        params.put("client_id", AliExpressConstant.APP_KEY);
        params.put("client_secret", AliExpressConstant.SIGN);
        params.put("redirect_uri", AliExpressConstant.TOKEN_REDIRECT_URL);
        params.put("code", code);
        try {
            String jsonToken = AuthService.getToken("gw.api.alibaba.com", params, true);
            //{"refresh_token_timeout":"20140827204416000-0700","aliId":"1095216790707","resource_owner":"cn1001434423","expires_in":"36000","refresh_token":"3d598277-68c6-41bc-ad18-c8e4e43b09da","access_token":"2e013f5f-eae2-4ed8-bd23-2681e3ba96c7"}JSON.parseObject(jsonString, Group.class);
            Map<String, String> result = JSON.parseObject(jsonToken, Map.class);

            ExpressUser user = new ExpressUser();
            user.setAccessToken(result.get(AliExpressConstant.TOKEN));
            user.setRefressToken(result.get(AliExpressConstant.REFRESH_TOKEN));
            user.setUserName(result.get("aliId"));
            this.memoryStore.add(result.get("aliId"), user);
            System.out.println(user);
            request.getSession().setAttribute(CUR_USER, user);
        } catch (Exception e) {
            logger.error("授权失败", e);
            return "error";
        }
        return "redirect:home";
    }



    @RequestMapping(value = "/sync", method = RequestMethod.POST)
    @ResponseBody
    public JSONResponse syncToAliExpress(HttpServletRequest request) {
        //
        String details = request.getParameter("detail");
        String subject = request.getParameter("subject");
        String keyword = request.getParameter("keyword");
        String categoryId = request.getParameter("categoryId");
        String productPrice = request.getParameter("productPrice");
        String deliveryTime = request.getParameter("deliveryTime");
        String attributes = request.getParameter("attributes"); //属性 json: [{},{},{}]

        ExpressUser usr = this.memoryStore.get(request.getParameter("id"));

        List<UploadPicResponse> urlOfImages = new ArrayList<UploadPicResponse>();

        String[] urls = request.getParameter("url").split(";");

        long start = System.currentTimeMillis();
        System.out.println("-------- upload pic");
        APIResponse response;
        try {
            for (String url : urls) {
                UploadPic uploadPic = new UploadPic();
                response = uploadPic.doCall(new UploadPicRequest(url), usr);
                UploadPicResponse tmp = new UploadPicResponse();
                tmp.setUrl(response.getMessage());
                urlOfImages.add(tmp);
            }

        } catch (ExpressAPIException e) {
            JSONResponse json = new JSONResponse();
            json.setMessage(e.getMessage());
            json.setState(e.getCode());
            return json;
        }

        long end = System.currentTimeMillis();
        System.out.println("-------- upload pic spends: "+(end - start));
        StringBuilder sb = new StringBuilder();
        for (UploadPicResponse each : urlOfImages) {
            sb.append(each.getUrl()).append(";");
        }

        Map<String, String> params = new HashMap<String, String>();
        params.put("detail", details);

        params.put("deliveryTime", deliveryTime);

        params.put("promiseTemplateId", "1");//fixed
        params.put("subject", subject);
        params.put("keyword", keyword);
        params.put("categoryId", categoryId);

        params.put("productPrice", productPrice);
        params.put("freightTemplateId", "228168473"); //fixed

        params.put("imageURLs", sb.toString()); //ali
        params.put("productUnit", "100000007"); //fixed KG

        params.put("packageType", "false");

        params.put("packageLength", "10");
        params.put("packageWidth", "10");
        params.put("packageHeight", "10");
        params.put("grossWeight", "0.4");

        params.put("isImageDynamic","true");

        params.put("wsValidNum", "30");//有效期
        params.put("aeopAeProductPropertys", attributes);

        params.put("access_token", usr.getAccessToken());

        String result = null;
        System.out.println("start deploy ... ");
        try {
            result = ApiCallService.callApiTest("https://gw.api.alibaba.com/openapi/", "param2/1/aliexpress.open/api.postAeProduct/" + AliExpressConstant.APP_KEY, AliExpressConstant.SIGN, params);
        } catch (ExpressAPIException e) {
            JSONResponse json = new JSONResponse();
            json.setMessage(e.getMessage());
            json.setState(e.getCode());
            return json;
        }

        System.out.println("start deploy ... " + (System.currentTimeMillis() - end));
        System.out.println(result);
        Map<String, String> map = JSON.parseObject(result, Map.class);
        JSONResponse json = new JSONResponse();
        json.setMessage(String.valueOf(map.get("productId")));
        json.setState(String.valueOf(map.get("success")));
        return json;
    }

    @RequestMapping(value = "/sync")
    public String syncToAliExpressGet(HttpServletRequest request) {
        return "redirect:home";
    }

    //228168473
    public static void main(String[] args) {
        Map<String, String> params = new HashMap<String, String>();
        params.put("detail", "1");
        params.put("deliveryTime", "1");
        params.put("promiseTemplateId", "1");//查到写死
        params.put("subject", "1");
        params.put("keyword", "1");
        params.put("categoryId", "1");

        params.put("productPrice", "1");
        params.put("freightTemplateId", "1");
        params.put("imageURLs", "http://pic6.nipic.com/20100324/723269_131504417118_2.jpg");
        params.put("productUnit", "100000007");

        params.put("packageType", "false");

        params.put("packageLength", "10");
        params.put("packageWidth", "10");
        params.put("packageHeight", "10");
        params.put("grossWeight", "0.4");

        params.put("access_token", "9eaa31ce-7064-4330-ad05-18f760616ffc");//request.getSession().getAttribute(AliExpressConstant.TOKEN).toString());
        List<String> paramValueList = new ArrayList<String>();
        if (params != null) {
            for (Map.Entry<String, String> entry : params.entrySet()) {
                paramValueList.add(entry.getKey() + entry.getValue());
            }
        }
        final String[] datas = new String[1 + paramValueList.size()];
        datas[0] = "param2/1/aliexpress.open/api.postAeProduct/5754679";
        Collections.sort(paramValueList);
        for (int i = 0; i < paramValueList.size(); i++) {
            datas[i + 1] = paramValueList.get(i);
        }
        byte[] signature = SecurityUtil.hmacSha1(datas, StringUtil.toBytes(AliExpressConstant.SIGN));
        System.out.println(StringUtil.encodeHexStr(signature));
        //http://gw.api.alibaba.com:80/openapi/
        //param2/1/aliexpress.open/api.postAeProduct/5754679detail1deliveryTime1promiseTemplateId1categoryId1subject1keyword=1&productPrice=1&freightTemplateId=1&imageURLs=http%3A%2F%2Fpic6.nipic.com%2F20100324%2F723269_131504417118_2.jpg&productUnit=100000007&packageType=false&packageLength=10&packageWidth=10&packageHeight=10&grossWeight=0.4&access_token=9eaa31ce-7064-4330-ad05-18f760616ffc&_aop_signature=A8ED5525F8D96AABC34FAF3B259773A45C910D1F
        String ss = "param2/1/aliexpress.open/api.postAeProduct/5754679detail1deliveryTime1promiseTemplateId1categoryId1subject1keyword=1&productPrice=1&freightTemplateId=1&imageURLs=http%3A%2F%2Fpic6.nipic.com%2F20100324%2F723269_131504417118_2.jpg&productUnit=100000007&packageType=false&packageLength=10&packageWidth=10&packageHeight=10&grossWeight=0.4&access_token=9eaa31ce-7064-4330-ad05-18f760616ffc&_aop_signature=A8ED5525F8D96AABC34FAF3B259773A45C910D1F";
        ss = ss.replaceAll("&", "").replaceAll("=", "");

        System.out.println(ss);

    }

    /**
     * 原生态返回JSON
     *
     * @param response
     * @param json
     */
    public void writeJSONStringToResponse(HttpServletResponse response,
                                          String json) {
        response.setCharacterEncoding("utf-8");
        PrintWriter pw = null;
        try {
            pw = response.getWriter();
            pw.print(json);
            pw.flush();
        } catch (IOException e) {
            e.printStackTrace();
        } finally {
            if (pw != null) pw.close();
        }
    }

    @RequestMapping(value = "/upload", method = RequestMethod.POST)
    public String handleFormUpload(
            @RequestParam("file") MultipartFile[] files) throws IOException {

        if (files.length >= 1) {
            for (MultipartFile file : files) {
                byte[] bytes = file.getBytes();
                System.out.println("qqqqqqqq");
            }
            // store the bytes somewhere
            return "redirect:/";
        } else {
            return "redirect:/";
        }
    }

    @RequestMapping("/testavi")
    @ResponseBody
    public byte[] getImage(HttpServletRequest request, HttpServletResponse response) throws IOException {

        InputStream is = this.getClass().getClassLoader().getResourceAsStream("20130730.avi");

        byte[] bytes = org.springframework.util.FileCopyUtils.copyToByteArray(is);

        response.setHeader("Content-Disposition", "attachment; filename=\"" + "20130730.avi" + "\"");
        response.setContentLength(bytes.length);
        response.setContentType("application/octet-stream");

        return bytes;
    }

    private class MapKeyComparator implements Comparator<String> {

        @Override
        public int compare(String str1, String str2) {

            return str1.compareTo(str2);
        }
    }
}
